route.ts 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import { NextRequest, NextResponse } from "next/server";
  2. import { STORAGE_KEY } from "../../../constant";
  3. async function handle(
  4. req: NextRequest,
  5. { params }: { params: { path: string[] } },
  6. ) {
  7. if (req.method === "OPTIONS") {
  8. return NextResponse.json({ body: "OK" }, { status: 200 });
  9. }
  10. const folder = STORAGE_KEY;
  11. const fileName = `${folder}/backup.json`;
  12. const requestUrl = new URL(req.url);
  13. const endpoint = requestUrl.searchParams.get("endpoint");
  14. const [protocol, ...subpath] = params.path;
  15. const endpointPath = subpath.join("/");
  16. // only allow MKCOL, GET, PUT
  17. if (req.method !== "MKCOL" && req.method !== "GET" && req.method !== "PUT") {
  18. return NextResponse.json(
  19. {
  20. error: true,
  21. msg: "you are not allowed to request " + params.path.join("/"),
  22. },
  23. {
  24. status: 403,
  25. },
  26. );
  27. }
  28. // for MKCOL request, only allow request ${folder}
  29. if (req.method == "MKCOL" && !endpointPath.endsWith(folder)) {
  30. return NextResponse.json(
  31. {
  32. error: true,
  33. msg: "you are not allowed to request " + params.path.join("/"),
  34. },
  35. {
  36. status: 403,
  37. },
  38. );
  39. }
  40. // for GET request, only allow request ending with fileName
  41. if (req.method == "GET" && !endpointPath.endsWith(fileName)) {
  42. return NextResponse.json(
  43. {
  44. error: true,
  45. msg: "you are not allowed to request " + params.path.join("/"),
  46. },
  47. {
  48. status: 403,
  49. },
  50. );
  51. }
  52. // for PUT request, only allow request ending with fileName
  53. if (req.method == "PUT" && !endpointPath.endsWith(fileName)) {
  54. return NextResponse.json(
  55. {
  56. error: true,
  57. msg: "you are not allowed to request " + params.path.join("/"),
  58. },
  59. {
  60. status: 403,
  61. },
  62. );
  63. }
  64. const targetUrl = `${protocol}://${endpoint + endpointPath}`;
  65. const method = req.headers.get("method") ?? undefined;
  66. const shouldNotHaveBody = ["get", "head"].includes(
  67. method?.toLowerCase() ?? "",
  68. );
  69. const fetchOptions: RequestInit = {
  70. headers: {
  71. authorization: req.headers.get("authorization") ?? "",
  72. },
  73. body: shouldNotHaveBody ? null : req.body,
  74. method,
  75. // @ts-ignore
  76. duplex: "half",
  77. };
  78. const fetchResult = await fetch(targetUrl, fetchOptions);
  79. console.log("[Any Proxy]", targetUrl, {
  80. status: fetchResult.status,
  81. statusText: fetchResult.statusText,
  82. });
  83. return fetchResult;
  84. }
  85. export const POST = handle;
  86. export const GET = handle;
  87. export const OPTIONS = handle;
  88. export const runtime = "edge";